﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LCA.Community.Web.Filters;
using LCA.Community.DAL.Interfaces;
using Microsoft.Practices.Unity;
using LCA.Community.DAL.Model;

namespace LCA.Community.Web.Controllers
{

    /// <summary>
    /// This controller is for administration porposes.
    /// </summary>
    public class AdminController : BaseController
    {
        /// <summary>
        /// Index action.
        /// </summary>
        /// <returns>Index view</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult Index()
        {
            return View("Index");
        }

        /// <summary>
        /// Action for deleting a post.
        /// </summary>
        /// <returns>View for deleting a post.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeletePosts()
        {
            return View("DeletePosts", PostsRepository.Entities);
        }

        /// <summary>
        /// Action for deleting a post given the author id
        /// </summary>
        /// <param name="id">The id of the author.</param>
        /// <returns>The partial view showing all post of the author.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeletePosts(string id)
        {
            var posts = PostsRepository.GetPostByUser(id);
            return PartialView("ShowPostsToRemove", posts);
        }

        /// <summary>
        /// Action for remove a post
        /// </summary>
        /// <param name="postID">The post ID.</param>
        /// <returns>Patial view with all post.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "PostNotFound", 2)]
        public ActionResult RemovePosts(string postID)
        {
            var post = PostsRepository.Get(postID);
            PostsRepository.Delete(post);

            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowPostsToRemove";
            partial.ViewData.Model = PostsRepository.Entities;
            return partial;
        }

        /// <summary>
        /// Action for deleting groups
        /// </summary>
        /// <returns>View for deleting groups.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteGroups()
        {
            var groups = GroupsRepository.Entities;
            return View("DeleteGroups", groups);
        }

        /// <summary>
        /// Action for deleting group given the name of the group
        /// </summary>
        /// <param name="id">The name of the group.</param>
        /// <returns>Partial view with the groups with the name.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteGroups(string id)
        {
            var groups = GroupsRepository.GetGroupsContainingName(id);
            return PartialView("ShowGroupsToRemove", groups);
        }

        /// <summary>
        /// Action for removing a group.
        /// </summary>
        /// <param name="groupID">The group ID.</param>
        /// <returns>The partial view with all groups.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "GroupNotFound", 2)]
        public ActionResult RemoveGroups(string groupID)
        {
            var group = GroupsRepository.Get(groupID);
            GroupsRepository.Delete(group);

            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowGroupsToRemove";
            partial.ViewData.Model = GroupsRepository.Entities;
            return partial;
        }

        /// <summary>
        /// Action for deleting users.
        /// </summary>
        /// <returns>View for deleting users.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteUsers()
        {
            var users = UsersRepository.Entities;
            return View("DeleteUsers", users);
        }

        /// <summary>
        /// Action for deleting users given the id of the user.
        /// </summary>
        /// <param name="id">The id of the user.</param>
        /// <returns>Partial view with the user containing the name.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteUsers(string id)
        {
            var users = UsersRepository.GetUserContainingName(id);
            return PartialView("ShowUsersToRemove", users);
        }

        /// <summary>
        /// Action for removing a user.
        /// </summary>
        /// <param name="userID">The id of the user.</param>
        /// <returns>Partial view with all users.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "UserNotFound", 2)]
        public ActionResult RemoveUser(string userID)
        {
            var user = UsersRepository.Get(userID);
            UsersRepository.Delete(user);
            var partialView = new PartialViewResult();
            partialView.ViewName = "ShowUsersToRemove";
            partialView.ViewData.Model = UsersRepository.Entities;
            return partialView;
        }

        /// <summary>
        /// Action for deleting comments.
        /// </summary>
        /// <returns>View for deleting comments.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteComments()
        {
            var comments = CommentsRepository.Entities;
            return View("DeleteComments", comments);
        }

        /// <summary>
        /// Action for deleting comments given the author
        /// </summary>
        /// <param name="id">The id of the user.</param>
        /// <returns>Partial view with the comments of the user.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "UserNotFound", 2)]
        public ActionResult DeleteComments(string id)
        {
            var comments = CommentsRepository.GetCommentsByUser(id);
            return PartialView("ShowCommentsToRemove", comments);
        }

        /// <summary>
        /// Action for removing comment
        /// </summary>
        /// <param name="commentID">The comment ID.</param>
        /// <returns>Partial view containing all comments.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "CommentNotFound", 2)]
        public ActionResult RemoveComment(string commentID)
        {
            var comment = CommentsRepository.Get(commentID);
            CommentsRepository.Delete(comment);
            var partialView = new PartialViewResult();
            partialView.ViewName = "ShowCommentsToRemove";
            partialView.ViewData.Model = CommentsRepository.Entities;
            return partialView;
        }

        /// <summary>
        /// Action for deleting events.
        /// </summary>
        /// <returns>View for deleting events.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteEvents()
        {
            var events = EventsRepository.Entities;
            return View("DeleteEvents", events);
        }

        /// <summary>
        /// Action for deleting events given the group id
        /// </summary>
        /// <param name="id">The group id.</param>
        /// <returns>Partial view containing all events of the group.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteEvents(string id)
        {
            var events = EventsRepository.GetEventsByGroup(id);
            return PartialView("ShowEventsToRemove", events);
        }

        /// <summary>
        /// Action for removing events.
        /// </summary>
        /// <param name="eventID">The event ID.</param>
        /// <returns>Partial view with all events.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "EventNotFound", 2)]
        public ActionResult RemoveEvent(string eventID)
        {
            var lcaEvent = EventsRepository.Get(eventID);
            EventsRepository.Delete(lcaEvent);
            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowEventsToRemove";
            partial.ViewData.Model = EventsRepository.Entities;
            return partial;
        }

        /// <summary>
        /// Action for deleting messages.
        /// </summary>
        /// <returns>View for deleting messages.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteMessages()
        {
            var messages = MessagesRepository.Entities;
            return View("DeleteMessages", messages);
        }

        /// <summary>
        /// Action for deleting messages given the user id of the sender
        /// </summary>
        /// <param name="id">The user id.</param>
        /// <returns>Partial view containing all messages of the given user.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult DeleteMessages(string id)
        {
            var messages = MessagesRepository.GetMessagesSentByUser(id);
            return PartialView("ShowMessagesToRemove", messages);
        }

        /// <summary>
        /// Action for removing messages
        /// </summary>
        /// <param name="messageID">The message ID.</param>
        /// <returns>Partial view containing all messages.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "MessageNotFound", 2)]
        public ActionResult RemoveMessages(string messageID)
        {
            var message = MessagesRepository.Get(messageID);
            MessagesRepository.Delete(message);
            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowMessagesToRemove";
            partial.ViewData.Model = MessagesRepository.Entities;
            return partial;
        }

        /// <summary>
        /// Action for managing administrators
        /// </summary>
        /// <returns>View for managing administrators.</returns>
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        public ActionResult ManageAdministrators()
        {
            var admins = AdministratorRepository.Entities;
            return View("ManageAdministrators", admins);
        }

        /// <summary>
        /// Action for adding an administrator.
        /// </summary>
        /// <param name="a">Administrator</param>
        /// <returns>Partial view with all administrators.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(InvalidOperationException), "AlreadyAdmin", 2)]
        [ErrorFilter(typeof(ArgumentException), "UserNotFound", 2)]
        public ActionResult AddAdministrator(Admin a)
        {
            a.PartitionKey = a.RowKey;
            AdminsRepository.Add(a);
            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowAdminsToRemove";
            partial.ViewData.Model = AdminsRepository.Entities;
            return partial;
        }

        /// <summary>
        /// Action for removing an administrator.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <returns>Partial view with all administrators.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [SecurityFilter(SecurityRequisites = "Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(Exception), "RequestError", 1)]
        [ErrorFilter(typeof(NullReferenceException), "NotAdmin", 2)]
        public ActionResult RemoveAdministrator(string userID)
        {
            var admin = AdminsRepository.Get(userID);
            AdminsRepository.Delete(admin);
            PartialViewResult partial = new PartialViewResult();
            partial.ViewName = "ShowAdminsToRemove";
            partial.ViewData.Model = AdminsRepository.Entities;
            return partial;
        }

        [Dependency]
        public IPostsRepository PostsRepository { get; set; }
        [Dependency]
        public IUsersRepository UsersRepository { get; set; }
        [Dependency]
        public ICommentsRepository CommentsRepository { get; set; }
        [Dependency]
        public IEventsRepository EventsRepository { get; set; }
        [Dependency]
        public IMessagesRepository MessagesRepository { get; set; }
        [Dependency]
        public IAdminsRepository AdministratorRepository { get; set; }
    }
}
